import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class PaperStatus extends StatefulWidget {
  const PaperStatus({super.key});

  @override
  _PaperStatusState createState() => _PaperStatusState();
}

class _PaperStatusState extends State<PaperStatus> {
  late final ThemeData _themeData = Theme.of(context);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    SystemChrome.setPreferredOrientations(// 使设备横屏显示
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        // appBar: AppBar(title: Text("自定义custom"),),
        body: SafeArea(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        child: CustomPaint(painter: CvasClipRect()),
      ),
    ));
  }
}

//基础图形绘制

// 其他裁剪 画布裁剪
class CvasClipRect extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint _paint = Paint();

    canvas.translate(size.width / 2, size.height / 2);

    // 绘制坐标以及网格
    _drawGrid(canvas, _paint, size);
    _drawCoor(canvas, _paint, size);

    //1、矩形裁剪:
    // var rect = Rect.fromCenter(center: Offset.zero, width: 360, height: 240);
    // canvas.clipRect(rect,
    //     doAntiAlias: true, clipOp: ui.ClipOp.intersect); // 裁剪画布
    // var colors = [
    //   Color(0xFFF60C0C),
    //   Color(0xFFF3B913),
    //   Color(0xFFE7F716),
    //   Color(0xFF3DF30B),
    //   Color(0xFF0DF6EF),
    //   Color(0xFF0829FB),
    //   Color(0xFFB709F4),
    // ];
    // var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0];
    // _paint.shader = ui.Gradient.linear(
    //     rect.centerLeft, rect.centerRight, colors, pos, TileMode.clamp);
    // _paint.blendMode = BlendMode.lighten;
    // canvas.drawPaint(_paint);

    //2 圆角矩形裁剪
    // var rect = Rect.fromCenter(center: Offset.zero, width: 200, height: 100);
    // canvas.clipRRect(RRect.fromRectAndRadius(rect, Radius.circular(30)));
    //
    // canvas.drawColor(Colors.red, BlendMode.darken);

    //3,路径裁剪
    Path path = Path();
    path.lineTo(80, 80);
    path.lineTo(-80, 80);
    path.close();
    canvas.clipPath(path);
    canvas.drawColor(Colors.red, BlendMode.darken);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 其他绘制，绘制阴影
class CvasDrawShadow extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();

    canvas.translate(size.width / 2, size.height / 2);

    // 绘制坐标以及网格
    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);

    // Path path = Path();
    // path.lineTo(80, 80);
    // path.lineTo(-80, 80);
    // path.close();
    // 阴影是根据路径绘制的，drawShadow 有四个参数:
    // 路径 path 、颜色 color、影深 elevation 和 内部是否显示 transparentOccluder
    // canvas.drawShadow(path, Colors.red, 3, true);
    // canvas.translate(200, 0);
    // canvas.drawShadow(path, Colors.red, 3, false);

    // 绘制 path  drawPath是一个极其重要的 API，为绘制提供了无限可能。主要用于将一个路径绘制出来。
    Path path = Path();
    path.lineTo(60, 60);
    path.lineTo(-60, 60);
    path.lineTo(60, -60);
    path.lineTo(-60, -60);
    path.close();
    canvas.drawPath(path, paint..style = PaintingStyle.fill);
    canvas.translate(140, 0);
    canvas.drawPath(
        path,
        paint
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 其他绘制  绘制颜色
class CvasDrawColor extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();

    canvas.translate(size.width / 2, size.height / 2);

    // 绘制坐标以及网格
    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);

    //在此基础上绘制颜色，需要传入颜色和混合模式
    // canvas.drawColor(Colors.blue, BlendMode.lighten);

    // 绘制画笔
    var colors = [
      Color(0xFFF60C0C),
      Color(0xFFF3B913),
      Color(0xFFE7F716),
      Color(0xFF3DF30B),
      Color(0xFF0DF6EF),
      Color(0xFF0829FB),
      Color(0xFFB709F4),
    ];
    var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0];
    paint.shader = ui.Gradient.linear(
        Offset(0, 0), Offset(size.width, 0), colors, pos, TileMode.clamp);
    paint.blendMode = BlendMode.lighten;
    canvas.drawPaint(paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 绘制类圆

class CvasDrawCircle extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    canvas.translate(size.width / 2, size.height / 2);
    // 绘制坐标以及网格
    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);
    //绘制圆角矩形
    //
    // paint
    //   ..color = Colors.blue
    //   ..style = PaintingStyle.fill;
    //
    // // drawCircle 画圆
    // canvas.save();
    // canvas.translate(-200, 0);
    // canvas.drawCircle(Offset(0, 0), 60, paint);
    // canvas.restore();
    //
    // // drawOval 椭圆。由矩形域决定
    // Rect rect = Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100);
    // canvas.drawOval(rect, paint);
    //
    // canvas.save();
    // canvas.translate(200, 0);
    // //drawArc(矩形区域,起始弧度,扫描弧度,是否连中心,画笔)
    // canvas.drawArc(rect, 0, pi / 2 * 3, true, paint);
    // canvas.restore();

    //drawArc 的第四参，表示是否使用中心点，下左图为 false,表示两端不与中间连线。
    // 中间图为 true，表示两端与中间连线。
    canvas.save();
    canvas.translate(-200, 0);
    Rect rect = Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100);
    canvas.drawArc(
        rect, 0, pi / 2 * 3, false, paint..style = PaintingStyle.stroke);
    canvas.restore();

    canvas.drawArc(
        rect,
        0,
        pi / 2 * 3,
        true,
        paint
          ..style = PaintingStyle.stroke
          ..color = Colors.red);

    canvas.save();
    canvas.translate(200, 0);
    canvas.rotate(0.45);
    canvas.drawArc(
        rect,
        0,
        pi / 2 * 3.4,
        true,
        paint
          ..style = PaintingStyle.stroke
          ..color = Colors.red);

    canvas.restore();

    canvas.save();
    canvas.translate(250, 0);
    canvas.drawCircle(Offset(0, 0), 10, paint..style = PaintingStyle.fill);
    canvas.drawCircle(Offset(30, 0), 10, paint..style = PaintingStyle.fill);
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 绘制圆角矩形

class CvasDrawRRect extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    canvas.translate(size.width / 2, size.height / 2);
    // 绘制坐标以及网格
    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);
    //绘制圆角矩形

    paint
      ..color = Colors.blue
      ..style = PaintingStyle.fill;
    // 1，绘制圆角矩形 XY构造，X：  X方向的圆角角度，Y： Y方向的圆角角度
    // Rect rectFromCenter =
    // Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160);
    // canvas.drawRRect(RRect.fromRectXY(rectFromCenter, 2, 2), paint);
    //
    // // 2， 绘制圆角矩形 fromLTRBXY构造
    // canvas.drawRRect(RRect.fromLTRBXY(-120, -120, -80, -80, 4, 4),
    //     paint..color = Colors.red);
    //
    // // 3,圆角矩形 fromLTRBR构造
    // canvas.drawRRect(RRect.fromLTRBR(80, -80, 120, -120, Radius.circular(10)),
    //     paint..color = Colors.orange);
    //
    // // 4, 圆角矩形 fromLTRBAndCorners构造
    // RRect ltrbAndCo = RRect.fromLTRBAndCorners(80, 80, 150, 150,
    //     bottomLeft: Radius.circular(20), topLeft: Radius.elliptical(6, 20));
    // canvas.drawRRect(ltrbAndCo, paint..color = Colors.red);
    // // 5, 圆角矩形 fromRectAndCorners
    // Rect rect = Rect.fromLTRB(-80, 80, -120, 120);
    // canvas.drawRRect(
    //     RRect.fromRectAndCorners(
    //       rect,
    //       topRight: Radius.circular(10),
    //     ),
    //     paint..color = Colors.black);

    // 【3】 绘制两个圆角矩形差域 drawDRRect
    Rect inRect =
        Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100);
    RRect inRRect = RRect.fromRectXY(inRect, 10, 10);
    Rect outRect =
        Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160);
    RRect outRRect = RRect.fromRectXY(outRect, 30, 30);

    canvas.drawDRRect(outRRect, inRRect, paint);

    Rect inRect2 = Rect.fromCenter(center: Offset(0, 0), width: 50, height: 50);
    RRect inRRect2 = RRect.fromRectXY(inRect2, 10, 10);
    Rect outRect2 =
        Rect.fromCenter(center: Offset(0, 0), width: 80, height: 80);
    RRect outRRect2 = RRect.fromRectXY(outRect2, 10, 10);

    canvas.drawDRRect(outRRect2, inRRect2, paint..color = Colors.green);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 绘制矩形
class CvasDrawRect extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    canvas.translate(size.width / 2, size.height / 2);
    // 绘制坐标以及网格
    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);
    //绘制矩形 drawRect

    paint
      ..color = Colors.blue
      ..style = PaintingStyle.fill;
    //【1】.矩形中心构造
    // Rect rectFromeCenter =
    //     Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160);
    // canvas.drawRect(rectFromeCenter, paint);
    // 2 矩形左上右下构造
    // Rect rectFromeLTRB = Rect.fromLTRB(-80, -80, -120, -120);
    // canvas.drawRect(rectFromeLTRB, paint..color = Colors.red);
    // Rect rectFromeLTRB2 = Rect.fromLTRB(80, -80, 120, -120);
    // canvas.drawRect(rectFromeLTRB2, paint..color = Colors.green);
    // Rect rectFromeLTRB3 = Rect.fromLTRB(80, 80, 120, 120);
    // canvas.drawRect(rectFromeLTRB3, paint..color = Colors.black);
    // Rect rectFromeLTRB4 = Rect.fromLTRB(-80, 80, -120, 120);
    // canvas.drawRect(rectFromeLTRB4, paint..color = Colors.pink);
    // 3 矩形 左上 宽高构造
    // Rect rectLTWH = Rect.fromLTWH(80, 80, 60, 60);
    // canvas.drawRect(rectLTWH, paint);
    // 4 矩形内切圆构造  以圆心的位置画一个内切圆，然后生成矩形
    Rect rectFromCircle = Rect.fromCircle(center: Offset(100, 100), radius: 20);
    canvas.drawRect(rectFromCircle, paint..color = Colors.red);

    // 5 两点 生成矩形
    Rect rectFromPoints = Rect.fromPoints(Offset(-80, -80), Offset(-120, -120));
    canvas.drawRect(rectFromPoints, paint..color = Colors.purple);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 绘制点
class CvasDrawPoints extends CustomPainter {
  final List<Offset> points = [
    Offset(-120, -20),
    Offset(-80, -80),
    Offset(-40, -40),
    Offset(0, -100),
    Offset(40, -140),
    Offset(80, -160),
    Offset(120, -100),
  ];
  Float32List pos = Float32List.fromList(
      [-120, -20, -80, -80, -40, -40, 0, -100, 40, -140, 80, -160, 120, -100]);

  void _drawPointsWithPoints(Canvas canvas, Paint paint) {
    paint
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1
      ..strokeCap = StrokeCap.round;
    //PointMode.points : 点模式
    // canvas.drawPoints(PointMode.points, points, paint);
    //PointMode.lines : 线段模式
    // canvas.drawPoints(PointMode.lines, points, paint);
    //PointMode.polygon : 多边形连线模式
    // canvas.drawPoints(PointMode.polygon, points, paint);
    // 绘点集: drawRawPoints
    paint
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10
      ..strokeCap = StrokeCap.round;
    canvas.drawRawPoints(ui.PointMode.points, pos, paint);
    paint.strokeWidth = 1;
    canvas.drawRawPoints(ui.PointMode.polygon, pos, paint);
  }

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    // 起点移到屏幕中间
    canvas.translate(size.width / 2, size.height / 2);

    _drawGrid(canvas, paint, size);
    _drawCoor(canvas, paint, size);
    _drawPointsWithPoints(canvas, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}

// 画布的变换和状态
class CvasStatusPaint extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    // 起点移到屏幕中间
    canvas.translate(size.width / 2, size.height / 2);

    _drawGrid(canvas, paint, size);

    _drawBlueCircle(canvas, paint);

    _drawYellowLine(canvas, paint);
    _drawRedLine(canvas, paint);
  }

  _drawYellowLine(Canvas canvas, Paint paint) {
    int count = 12;
    paint
      ..color = Colors.orangeAccent
      ..strokeWidth = 5
      ..strokeCap = StrokeCap.round;
    canvas.save();
    for (int i = 0; i < count; i++) {
      // 2 * pi 等于一个圆周长，除于count数量，计算出每一个count旋转的角度，然后旋转画布
      var step = 2 * pi / count;
      canvas.drawLine(Offset(70, 0), Offset(100, 0), paint);
      canvas.rotate(step);
    }
    canvas.restore();
  }

  _drawBlueCircle(Canvas canvas, Paint paint) {
    paint
      ..color = Colors.blue
      ..style = PaintingStyle.fill;
    canvas.drawCircle(const Offset(0, 0), 50, paint);
  }

  _drawRedLine(Canvas canvas, Paint paint) {
    paint
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10
      ..strokeCap = StrokeCap.round;
    canvas.drawLine(Offset(20, 20), Offset(50, 50), paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}

void _drawCoor(Canvas canvas, Paint _paint, Size size) {
  _paint
    ..color = Colors.blue
    ..strokeWidth = 2;
  Offset yEndPoint = Offset(0, size.height / 2);
  canvas.drawLine(Offset(0, -size.height / 2), yEndPoint, _paint);

  canvas.drawLine(yEndPoint, Offset(-10, size.height / 2 - 10), _paint);
  canvas.drawLine(yEndPoint, Offset(10, size.height / 2 - 10), _paint);

  Offset xEndPoint = Offset(size.width / 2, 0);
  canvas.drawLine(Offset(-size.width / 2, 0), xEndPoint, _paint);
  canvas.drawLine(xEndPoint, Offset(size.width / 2 - 10, -10), _paint);
  canvas.drawLine(xEndPoint, Offset(size.width / 2 - 10, 10), _paint);
}

_drawGrid(Canvas canvas, Paint paint, Size size) {
  // 绘制四分之一的网格 ,要画全屏的画需要用镜像的方法
  //如果是相同或者对称的对象，可以通过缩放进行对称变化。
  // 沿x轴镜像，就相当于canvas.scale(1, -1)；
  // 沿y轴镜像，就相当于canvas.scale(-1, 1)；
  // 沿原点镜像，就相当于canvas.scale(-1, -1)；
  _drawHalfGrid(canvas, paint, size);
  // x轴镜像
  canvas.save();
  canvas.scale(1, -1);
  _drawHalfGrid(canvas, paint, size);
  canvas.restore();
  // y轴镜像
  canvas.save();
  canvas.scale(-1, 1);
  _drawHalfGrid(canvas, paint, size);
  canvas.restore();
  // 原点镜像
  canvas.save();
  canvas.scale(-1, -1);
  _drawHalfGrid(canvas, paint, size);
  // canvas.drawLine(Offset(0, 0), Offset(100, 100), paint);
  canvas.restore();
}

_drawHalfGrid(Canvas canvas, Paint paint, Size size) {
  // 画网格
  double step = 20;
  paint
    ..color = Colors.grey
    ..strokeWidth = 1
    ..style = PaintingStyle.stroke;

  // 绘制横线
  canvas.save();
  // 计算绘制的 1/4 屏幕能画多少条线，然后循环就可以了
  for (int i = 0; i < size.height / 2 / step; i++) {
    canvas.drawLine(Offset(0, 0), Offset(size.width / 2, 0), paint);
    canvas.translate(0, step);
  }
  canvas.restore();
  // 绘制竖线
  canvas.save();
  // 计算绘制的 1/4 屏幕能画多少条线，然后循环就可以了
  for (int i = 0; i < size.width / 2 / step; i++) {
    canvas.drawLine(Offset(0, 0), Offset(0, size.height / 2), paint);
    canvas.translate(step, 0);
  }
  canvas.restore();
}
